package agend.behaviours.one_to_one;

import jade.core.AID;
import jade.core.behaviours.Behaviour;
import jade.lang.acl.ACLMessage;
import jade.lang.acl.MessageTemplate;
import jade.lang.acl.UnreadableException;

import java.io.IOException;
import java.util.List;

import agend.agents.AgendAgent;
import agend.util.PerfomanceMeasure;
import dto.utils.DataTransferObject;
import dto.utils.SingleEvent;

public class OneToOneSenderBehaviour extends Behaviour {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	private DataTransferObject dto;

	private int step;

	private MessageTemplate messageTemplate;
	
	private SingleEvent singleEvent;

	public OneToOneSenderBehaviour(DataTransferObject dto) {

		PerfomanceMeasure.updateCountTentativi();
		this.dto = dto;
		step = 0;
	}

	@Override
	public void action() {


		// TODO Auto-generated method stub
		switch (step) {

		case 0:
		{	
			List<SingleEvent> myEvents=((AgendAgent)myAgent).getGoogleServices().getEventsByRange(dto.getStartTime(), dto.getEndTime());

			dto.setEvents(myEvents);

			step = 1;

			break;
		}
		case 1:
		{
			ACLMessage message = new ACLMessage(ACLMessage.CFP);
			
			message.setSender(myAgent.getAID());
			message.addReceiver(new AID(dto.getReceivers().get(0), AID.ISLOCALNAME));
			message.setConversationId("ONE-to-ONE");
			message.setReplyWith("cfp"+System.currentTimeMillis());
	
			messageTemplate = MessageTemplate.and(MessageTemplate.MatchConversationId("ONE-to-ONE"),
													MessageTemplate.MatchInReplyTo(message.getReplyWith()));
			
			try {
				
				message.setContentObject(dto);
				myAgent.send(message);
				step = 2;
				
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
				step = 5;
			}
			

			break;
		}
		case 2:
		{
			
			ACLMessage message = myAgent.receive(messageTemplate);
			
			if(message != null){
				
				singleEvent = null;
				try {
					singleEvent = (SingleEvent) message.getContentObject();
				} catch (UnreadableException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				
				if(singleEvent.isValid())
					step=3;
				else{
					
					PerfomanceMeasure.getPerformanceMeasure();
					step=5;	
				}
			}			
			else 
				block();
			
			break;
		}
		case 3:
		{
			DataTransferObject dataTransferObject = new DataTransferObject();
			dataTransferObject.setStartTime(singleEvent.getStartTime());
			dataTransferObject.setEndTime(singleEvent.getEndTime());

			ACLMessage message = new ACLMessage(ACLMessage.INFORM);

			message.setSender(myAgent.getAID());
			message.addReceiver(new AID(dto.getReceivers().get(0), AID.ISLOCALNAME));
			message.setConversationId("IS-FREE");
			message.setReplyWith("info"+System.currentTimeMillis());
			
			messageTemplate = MessageTemplate.and(MessageTemplate.MatchConversationId("IS-FREE"),
													MessageTemplate.MatchInReplyTo(message.getReplyWith()));

			try {
				message.setContentObject(dataTransferObject);
				myAgent.send(message);

				step = 4;

			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
			break;
		}
		case 4:
		{
			ACLMessage replay = myAgent.receive(messageTemplate);

			if(replay!=null)
			{
				if(replay.getPerformative() == ACLMessage.CONFIRM)
				{
					List<SingleEvent> myEvents=((AgendAgent)myAgent).getGoogleServices().getEventsByRange(singleEvent.getStartTime(), singleEvent.getEndTime());
					
					if(myEvents.isEmpty() || myEvents==null)
					{
						String id = ((AgendAgent)myAgent).getGoogleServices().setEvent(dto.getTitle(), dto.getDescription(), dto.getWhere(), singleEvent, dto.getReceivers(), dto.getTimeZone());
						PerfomanceMeasure.getPerformanceMeasure(1, singleEvent.getPunteggio(), dto.getStartTime(), dto.getEndTime(), singleEvent.getStartTime());
						
						((AgendAgent)myAgent).addEventsToMap(id, dto);
					}
					else
						resetAppointment();
						
				}
				else if(replay.getPerformative() == ACLMessage.FAILURE)
					resetAppointment();
				
				step=5;
			}
			else
				block();
			
			break;
		}
		default:
			break;
		}

	}
	
	private void resetAppointment(){
		
		OneToOneSenderBehaviour oneToOneSenderBehaviour = new OneToOneSenderBehaviour(dto);
		myAgent.addBehaviour(oneToOneSenderBehaviour);
	}

	@Override
	public boolean done() {
		// TODO Auto-generated method stub
		return (step==5);
	}

}
